--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
notify.py main (dac94b89) Text, 6.27 KB
T8b949e#!/usr/bin/env python3
T8b949e# nomadForum - a forum on the NomadNetwork
T8b949e# Copyright (C) 2023-2026 AutumnSpark1226
T8b949e#
T8b949e# This program is free software: you can redistribute it and/or modify
T8b949e# it under the terms of the GNU General Public License as published by
T8b949e# the Free Software Foundation, either version 3 of the License, or
T8b949e# (at your option) any later version.
T8b949e#
T8b949e# This program is distributed in the hope that it will be useful,
T8b949e# but WITHOUT ANY WARRANTY; without even the implied warranty of
T8b949e# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
T8b949e# GNU General Public License for more details.
T8b949e#
T8b949e# You should have received a copy of the GNU General Public License
T8b949e# along with this program. If not, see <https://www.gnu.org/licenses/>.
Tff7b72import T7ee787os
Tff7b72import T7ee787socket
Tff7b72import T7ee787string
Tff7b72from T7ee787threading Tff7b72import Te6edf3Thread
Tff7b72from T7ee787time Tff7b72import Te6edf3sleep
Tff7b72import T7ee787LXMF
Tff7b72import T7ee787RNS
Tff7b72import T7ee787main
Tff7b72from T7ee787main Tff7b72import Te6edf3conf
T8b949e# Set the path of the Unix socket
Te6edf3socket_path Tff7b72= Ta5d6ff"Ta5d6ff/tmp/nomadForum_socketTa5d6ff"
Te6edf3propagation_node_address Tff7b72= Ta5d6ff"Ta5d6fff141f039b3b88b7a2d5c6048c7adaafbTa5d6ff" T8b949e# This is the LXMF propagation node hosted on SparkN0de. I recommend using a propagation node running on the same host / that is always available
Te6edf3message_queue Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3queue_processing_running Tff7b72= Tff7b72False
Te6edf3reticulumTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffReticulum
Te6edf3routerTb4b4b4: Te6edf3LXMFTff7b72.Td2a8ffLXMRouter
Te6edf3identTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffIdentity
Te6edf3sourceTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffDestination
Te6edf3identity_path Tff7b72= Te6edf3confTff7b72.Td2a8ffstorage_path Tff7b72+ Ta5d6ff"Ta5d6ff/notification_identityTa5d6ff"
Te6edf3router_storage_path Tff7b72= Te6edf3confTff7b72.Td2a8ffstorage_path Tff7b72+ Ta5d6ff"Ta5d6ff/router_storageTa5d6ff"
Tff7b72def Td2a8ffsetup_lxmfTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72global Te6edf3reticulumTb4b4b4, Te6edf3routerTb4b4b4, Te6edf3sourceTb4b4b4, Te6edf3ident
Te6edf3reticulum Tff7b72= Te6edf3RNSTff7b72.Td2a8ffReticulumTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3identity_pathTb4b4b4)Tb4b4b4:
Te6edf3ident Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffrom_fileTb4b4b4(Te6edf3identity_pathTb4b4b4)
Tff7b72if Te6edf3ident Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffLoaded identityTa5d6ff"Tb4b4b4)
Tff7b72elseTb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffCould not load identityTa5d6ff"Tb4b4b4)
Te6edf3exitTb4b4b4(T79c0ff1Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3ident Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTb4b4b4(Tb4b4b4)
Te6edf3identTff7b72.Td2a8ffto_fileTb4b4b4(Te6edf3identity_pathTb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffCreated new identityTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3router_storage_pathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Te6edf3router_storage_pathTb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffcreated LXMF storage pathTa5d6ff"Tb4b4b4)
Te6edf3router Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMRouterTb4b4b4(Te6edf3identityTff7b72=Te6edf3identTb4b4b4, Te6edf3storagepathTff7b72=Te6edf3router_storage_pathTb4b4b4)
T8b949e# set propagation node
Te6edf3routerTff7b72.Td2a8ffset_outbound_propagation_nodeTb4b4b4(Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3propagation_node_addressTb4b4b4)Tb4b4b4)
Te6edf3source Tff7b72= Te6edf3routerTff7b72.Td2a8ffregister_delivery_identityTb4b4b4(
Te6edf3identTb4b4b4, Te6edf3display_nameTff7b72=Te6edf3confTff7b72.Td2a8ffforum_name Tff7b72+ Ta5d6ff"Ta5d6ff noficationsTa5d6ff"
Tb4b4b4)
Te6edf3routerTff7b72.Td2a8ffannounceTb4b4b4(Te6edf3sourceTff7b72.Td2a8ffhashTb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffannouncement sentTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8ffdelivery_callbackTb4b4b4(Te6edf3lxmTb4b4b4)Tb4b4b4:
Tff7b72if Tb4b4b4(
Te6edf3lxmTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffFAILED
Tff7b72and Tffa657hasattrTb4b4b4(Te6edf3lxmTb4b4b4, Ta5d6ff"Ta5d6fftry_propagation_on_failTa5d6ff"Tb4b4b4)
Tff7b72and Te6edf3lxmTff7b72.Td2a8fftry_propagation_on_fail
Tb4b4b4)Tb4b4b4:
Te6edf3lxmTff7b72.Td2a8fftry_propagation_on_fail Tff7b72= Tff7b72None
Te6edf3lxmTff7b72.Td2a8ffdelivery_attempts Tff7b72= T79c0ff0
Tff7b72del Te6edf3lxmTff7b72.Td2a8ffnext_delivery_attempt
Te6edf3lxmTff7b72.Td2a8ffpacked Tff7b72= Tff7b72None
Te6edf3lxmTff7b72.Td2a8ffdesired_method Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPROPAGATED
Te6edf3routerTff7b72.Td2a8ffhandle_outboundTb4b4b4(Te6edf3lxmTb4b4b4)
Tff7b72def Td2a8ffsend_notificationTb4b4b4(Te6edf3detailsTb4b4b4: Tffa657listTb4b4b4[Tffa657strTb4b4b4]Tb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
Te6edf3recipient_hash Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffhash_from_name_and_identityTb4b4b4(
Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4, Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3detailsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)
Tb4b4b4)
T8b949e# wait for path
Te6edf3timeout_counter Tff7b72= T79c0ff0
Tff7b72if Tff7b72not Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Te6edf3recipient_hashTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffrequest_pathTb4b4b4(Te6edf3recipient_hashTb4b4b4)
Tff7b72while Tff7b72not Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Te6edf3recipient_hashTb4b4b4)Tb4b4b4:
Te6edf3sleepTb4b4b4(T79c0ff0.1Tb4b4b4)
Te6edf3timeout_counter Tff7b72+Tff7b72= T79c0ff1
Tff7b72if Te6edf3timeout_counter Tff7b72> T79c0ff1000Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffCould not find recipient: Ta5d6ff" Tff7b72+ Te6edf3detailsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)
Tff7b72return
Te6edf3recipient_identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffrecallTb4b4b4(Te6edf3recipient_hashTb4b4b4)
Te6edf3dest Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(
Te6edf3recipient_identityTb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffOUTTb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4,
Ta5d6ff"Ta5d6fflxmfTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdeliveryTa5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3lxm Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTb4b4b4(
Te6edf3destTb4b4b4,
Te6edf3sourceTb4b4b4,
Te6edf3detailsTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffNew notificationTa5d6ff"Tb4b4b4,
Te6edf3desired_methodTff7b72=Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3routerTff7b72.Td2a8ffget_outbound_propagation_nodeTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3lxmTff7b72.Td2a8fftry_propagation_on_fail Tff7b72= Tff7b72True
Te6edf3lxmTff7b72.Td2a8ffregister_delivery_callbackTb4b4b4(Te6edf3delivery_callbackTb4b4b4)
Te6edf3lxmTff7b72.Td2a8ffregister_failed_callbackTb4b4b4(Te6edf3delivery_callbackTb4b4b4)
Te6edf3routerTff7b72.Td2a8ffhandle_outboundTb4b4b4(Te6edf3lxmTb4b4b4)
Tff7b72def Td2a8ffprocess_queueTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72global Te6edf3queue_processing_running
Te6edf3queue_processing_running Tff7b72= Tff7b72True
Te6edf3length Tff7b72= Tffa657lenTb4b4b4(Te6edf3message_queueTb4b4b4)
Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(Te6edf3lengthTb4b4b4)Tb4b4b4:
Te6edf3send_notificationTb4b4b4(Te6edf3message_queueTff7b72.Td2a8ffpopTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4)
T8b949e# call the function again to process new entries
Tff7b72if Tffa657lenTb4b4b4(Te6edf3message_queueTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3process_queueTb4b4b4(Tb4b4b4)
Te6edf3queue_processing_running Tff7b72= Tff7b72False
Tff7b72def Td2a8ffrun_serverTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e# try to remove already existing socket
Tff7b72tryTb4b4b4:
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3socket_pathTb4b4b4)
Tff7b72except Tf85149OSErrorTb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3socket_pathTb4b4b4)Tb4b4b4:
Tff7b72raise
Te6edf3server Tff7b72= Te6edf3socketTff7b72.Td2a8ffsocketTb4b4b4(Te6edf3socketTff7b72.Td2a8ffAF_UNIXTb4b4b4, Te6edf3socketTff7b72.Td2a8ffSOCK_STREAMTb4b4b4)
Te6edf3serverTff7b72.Td2a8ffbindTb4b4b4(Te6edf3socket_pathTb4b4b4)
Te6edf3serverTff7b72.Td2a8fflistenTb4b4b4(T79c0ff1Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72while Tff7b72TrueTb4b4b4:
Te6edf3connectionTb4b4b4, Te6edf3_ Tff7b72= Te6edf3serverTff7b72.Td2a8ffacceptTb4b4b4(Tb4b4b4)
Te6edf3continue_receiving Tff7b72= Tff7b72True
Tff7b72while Te6edf3continue_receivingTb4b4b4:
Te6edf3destination Tff7b72= Te6edf3connectionTff7b72.Td2a8ffrecvTb4b4b4(T79c0ff32Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Tb4b4b4)
Te6edf3message Tff7b72= Te6edf3connectionTff7b72.Td2a8ffrecvTb4b4b4(T79c0ff4096Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Tb4b4b4)
Tff7b72if Tb4b4b4(
Te6edf3destination
Tff7b72and Te6edf3message
Tff7b72and Tffa657lenTb4b4b4(Te6edf3destinationTb4b4b4) Tff7b72== T79c0ff32
Tff7b72and Tffa657setTb4b4b4(Te6edf3destinationTb4b4b4)Tff7b72.Td2a8ffissubsetTb4b4b4(Tffa657setTb4b4b4(Te6edf3stringTff7b72.Td2a8ffhexdigitsTb4b4b4)Tb4b4b4)
Tb4b4b4)Tb4b4b4:
Te6edf3message_queueTff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4[Te6edf3destinationTb4b4b4, Te6edf3messageTb4b4b4]Tb4b4b4)
Te6edf3connectionTff7b72.Td2a8ffsendTb4b4b4(Ta5d6ff"Ta5d6ffokTa5d6ff"Tff7b72.Td2a8ffencodeTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3connectionTff7b72.Td2a8ffsendTb4b4b4(Ta5d6ff"Ta5d6fferrorTa5d6ff"Tff7b72.Td2a8ffencodeTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3status Tff7b72= Te6edf3connectionTff7b72.Td2a8ffrecvTb4b4b4(T79c0ff32Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Tb4b4b4)
Te6edf3continue_receiving Tff7b72= Te6edf3status Tff7b72== Ta5d6ff"Ta5d6ffcontinueTa5d6ff"
Tff7b72if Te6edf3continue_receivingTb4b4b4:
Te6edf3connectionTff7b72.Td2a8ffsendTb4b4b4(Ta5d6ff"Ta5d6ffsendNextTa5d6ff"Tff7b72.Td2a8ffencodeTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3connectionTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3queue_processing_runningTb4b4b4:
Te6edf3thread Tff7b72= Te6edf3ThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3process_queueTb4b4b4)
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72finallyTb4b4b4:
Te6edf3connectionTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3socket_pathTb4b4b4)
T8b949e# this method will be called by the program that needs to send a notification
Tff7b72def Td2a8ffadd_notificationTb4b4b4(Te6edf3messageTb4b4b4: Tffa657listTb4b4b4[Tffa657strTb4b4b4]Tb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
Te6edf3client Tff7b72= Te6edf3socketTff7b72.Td2a8ffsocketTb4b4b4(Te6edf3socketTff7b72.Td2a8ffAF_UNIXTb4b4b4, Te6edf3socketTff7b72.Td2a8ffSOCK_STREAMTb4b4b4)
Te6edf3clientTff7b72.Td2a8ffconnectTb4b4b4(Te6edf3socket_pathTb4b4b4)
Te6edf3clientTff7b72.Td2a8ffsendTb4b4b4(Te6edf3messageTb4b4b4[T79c0ff0Tb4b4b4]Tff7b72.Td2a8ffencodeTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3clientTff7b72.Td2a8ffsendTb4b4b4(Te6edf3messageTb4b4b4[T79c0ff1Tb4b4b4]Tff7b72.Td2a8ffencodeTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3response Tff7b72= Te6edf3clientTff7b72.Td2a8ffrecvTb4b4b4(T79c0ff128Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3response Tff7b72!= Ta5d6ff"Ta5d6ffokTa5d6ff"Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffsomething went wrongTa5d6ff"Tb4b4b4)
Te6edf3clientTff7b72.Td2a8ffsendTb4b4b4(Ta5d6ff"Ta5d6ffendTa5d6ff"Tff7b72.Td2a8ffencodeTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3clientTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72__name__ Tff7b72== Ta5d6ff"Ta5d6ff__main__Ta5d6ff"Tb4b4b4:
Te6edf3setup_lxmfTb4b4b4(Tb4b4b4)
Te6edf3run_serverTb4b4b4(Tb4b4b4)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────